import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;


class Node {
    int x;
    int y;
    Node(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class day230415 {
    // 年终奖
    public int getMost(int[][] board) {
        int[][] dp = new int[6][6];
        dp[0][0] = board[0][0];
        // 初始化
        // 第一列, 只能上面走过来
        for (int i = 1; i < 6; i++) {
            dp[i][0] = board[i][0] + dp[i - 1][0];
        }
        // 第一行, 只能左边走过来
        for (int i = 1; i < 6; i++) {
            dp[0][i] = board[0][i] + dp[0][i - 1];
        }
        for (int i = 1; i < 6; i++) {
            for (int j = 1; j < 6; j++) {
                if (dp[i][j - 1] > dp[i - 1][j]) {
                    // 左边的价值比上面的价值大
                    // 当前价值 加 左边的
                    dp[i][j] = board[i][j] + dp[i][j - 1];
                } else {
                    // 上面的大
                    dp[i][j] = board[i][j] + dp[i - 1][j];
                }
            }
        }
        return dp[5][5];
    }

    // 迷宫问题
    // 找到一条路径不直接停止, 继续找有没有其他路径, 更新最短路径
    // (x, y) 判断是否越界, 是否有障碍, 是否走过
    // 如果都没有, 将当前节点保存到当前路径中
    // 如果抵达终点(右下角), 就产生了新的一条路径, 更新更短路径
    // 继续搜索 (x, y) 的四个方向

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int row = sc.nextInt();
        int col = sc.nextInt();
        int[][] maze = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                maze[i][j] = sc.nextInt();
            }
        }
        int[][] flag = new int[row][col];
        ArrayList<Node> path = new ArrayList<>();
        ArrayList<Node> minPath = new ArrayList<>();
        getMinPath(maze, row, col, 0, 0, flag, path, minPath);

        for (Node n : minPath) {
            System.out.printf("(%d,%d)\n", n.x, n.y);
        }
    }

    // maze 迷宫矩阵, 行 row, 列 col
    // x, y 当前位置
    // flag 用来标记当前位置是否走过
    // path 保存当前路径
    // minPath 保存最短路径
    public static void getMinPath(int[][] maze, int row, int col, int x, int y,
                                  int[][] flag, ArrayList<Node> path, ArrayList<Node> minPath) {
        // 判断 (x, y) 是否越界, 是否有障碍, 是否走过
        if (x < 0 || x >= row || y < 0 || y >= col) {
            return;
        }
        if (maze[x][y] == 1 || flag[x][y] == 1) {
            return;
        }
        // 将当前节点存入路径
        path.add(new Node(x, y));
        // 标记当前位置为走过
        flag[x][y] = 1;
        // 判断当前是否为终点
        if (x == row - 1 && y == col - 1) {
            // 新的路径产生了, 判断是否为更短路径
            if (minPath.size() == 0 || minPath.size() > path.size()) {
                // 更新最短路径
                minPath.clear();
                minPath.addAll(path);
            }
        }
        // 搜索(x, y)的上下左右.
        getMinPath(maze, row, col, x - 1, y, flag, path, minPath);
        getMinPath(maze, row, col, x + 1, y, flag, path, minPath);
        getMinPath(maze, row, col, x, y - 1, flag, path, minPath);
        getMinPath(maze, row, col, x, y + 1, flag, path, minPath);

        // 搜索完四个方向, 把当前路径删除, 回退, 寻找新的路径
        path.remove(path.size() - 1);
        flag[x][y] = 0;
    }



    // 没考虑最短路径
    public static void main1(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[][] maze = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                maze[i][j] = sc.nextInt();
            }
        }

        // 存放路径节点
        Deque<String> deque = new LinkedList<>();

        // 标识这一格是否走过, 不能走回头路
        int[][] flag = new int[n][m];
        flag[0][0] = 1;

        // 递归
        func(maze, 0, 0, deque, flag);

        // 输出
        while (!deque.isEmpty()) {
            System.out.println(deque.pollFirst());
        }
    }

    private static boolean func(int[][] maze, int i, int j, Deque<String> deque, int[][] flag) {
        // 标记这一格，防止走回头路
        flag[i][j] = 1;
        String p = "(" + i + ',' + j + ')';
        // 将当前节点入队
        deque.addLast(p);

        if (i == maze.length - 1 && j == maze[0].length - 1) {
            // 抵达终点
            return true;
        }

        // 表示当前节点的上下左右有没有路走
        boolean left = false;
        boolean right = false;
        boolean up = false;
        boolean under = false;

        // 不能越界

        if (j + 1 != maze[0].length) {
            // 右, 不能撞墙，不能走回头路
            if (maze[i][j + 1] != 1 && flag[i][j + 1] != 1) {
                right = func(maze, i, j + 1, deque, flag);
            }
        }

        if (i + 1 != maze.length) {
            // 下, 不能撞墙，不能走回头路
            if (maze[i + 1][j] != 1 && flag[i + 1][j] != 1) {
                under = func(maze, i + 1, j, deque, flag);
            }
        }

        if (i - 1 != -1) {
            // 往上走，不能撞墙，不能走回头路
            if (maze[i - 1][j] != 1 && flag[i - 1][j] != 1) {
                up = func(maze, i - 1, j, deque, flag);
            }
        }

        if (j - 1 != -1) {
            // 左, 不能撞墙，不能走回头路
            if (maze[i][j - 1] != 1 && flag[i][j - 1] != 1) {
                left = func(maze, i, j - 1, deque, flag);
            }
        }


        // 上下左右四个方向都递归完
        // 如果都没有路, 这个节点出队
        if (!up && !under && !left && !right) {
            deque.removeLast();
            return false;
        }

        // 否则，这个这个节点，是通路上的节点
        return true;
    }
}
